package lj.courseinterect.utils;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.codec.Hex;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class TokenUtils
{
    static long EXPIRE_TIME = 1000L * 60 * 60 * 24 * 7;
	public static final String MAGIC_KEY = "youguesswhat";

	public static String createToken(UserDetails userDetails)
	{
		/* Expires in one hour */
		long expires = System.currentTimeMillis() + EXPIRE_TIME;

		StringBuilder tokenBuilder = new StringBuilder();
		tokenBuilder.append(userDetails.getUsername());
		tokenBuilder.append(":");
		tokenBuilder.append(expires);
		tokenBuilder.append(":");
		tokenBuilder.append(TokenUtils.computeSignature(userDetails, expires));

		return tokenBuilder.toString();
	}

    /**
     * 计算签名
     * @param userDetails security用户信息
     * @param expires 时间
     * @return 签名
     */
	public static String computeSignature(UserDetails userDetails, long expires)
	{
		StringBuilder signatureBuilder = new StringBuilder();
		signatureBuilder.append(userDetails.getUsername());
		signatureBuilder.append(":");
		signatureBuilder.append(expires);
		signatureBuilder.append(":");
		signatureBuilder.append(userDetails.getPassword());
		signatureBuilder.append(":");
		signatureBuilder.append(TokenUtils.MAGIC_KEY);

		MessageDigest digest;
		try {
			digest = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			throw new IllegalStateException("No MD5 algorithm available!");
		}

		return new String(Hex.encode(digest.digest(signatureBuilder.toString().getBytes())));
	}

    /**
     * Token中获得username
     * @param authToken token
     * @return 获得的username
     */
	public static String getUserNameFromToken(String authToken)
	{
		if (null == authToken) {
			return null;
		}

		String[] parts = authToken.split(":");
		return parts[0];
	}


    /**
     * 验证Token是否过期
     * @param authToken Token
     * @param userDetails  security用户信息
     * @return token是否可用
     */
	public static boolean validateToken(String authToken, UserDetails userDetails)
	{
        try{
            String[] parts = authToken.split(":");
            long expires = Long.parseLong(parts[1]);
            String signature = parts[2];

            return expires >= System.currentTimeMillis()
                && signature.equals(TokenUtils.computeSignature(userDetails, expires));
        } catch (Exception ex){
            return false;
        }

    }
}